import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';
import { useUserStore } from '@/store/userStore';
import { useLoginStore } from '@/store/loginStore';
import { ElMessage } from 'element-plus';

// 创建请求实例
const instance: AxiosInstance = axios.create({
    baseURL: '/api',
    timeout: 6000,
    headers: {
        'Content-Type': 'application/json;charset=UTF-8'
    }
});

// 存储请求映射
const pendingMap = new Map();

// 生成请求Key
function generateReqKey(config: AxiosRequestConfig) {
    const { method, url, params, data } = config;
    return [method, url, JSON.stringify(params), JSON.stringify(data)].join('&');
}

// 添加请求
function addPending(config: AxiosRequestConfig) {
    const requestKey = generateReqKey(config);
    config.cancelToken = config.cancelToken || new axios.CancelToken(cancel => {
        if (!pendingMap.has(requestKey)) {
            pendingMap.set(requestKey, cancel);
        }
    });
}

// 移除请求
function removePending(config: AxiosRequestConfig) {
    const requestKey = generateReqKey(config);
    if (pendingMap.has(requestKey)) {
        const cancelToken = pendingMap.get(requestKey);
        cancelToken(requestKey);
        pendingMap.delete(requestKey);
    }
}

// 请求拦截器
instance.interceptors.request.use(
    (config) => {
        removePending(config);
        addPending(config);

        // 添加token
        const userStore = useUserStore()
        const token = userStore.userInfo?.goaliasToken
        if (token && token.length > 0) {
            config.headers['Goalias-Token'] = `Bearer ${token}`;
        }

        return config;
    },
    (error) => {
        return Promise.reject(error);
    }
);

// 响应拦截器
instance.interceptors.response.use(
    (response: AxiosResponse) => {
        removePending(response.config);
        const res = response.data;
        // 根据后端约定的状态码判断请求是否成功
        if (res.code === 200) {
            return res;
        }

        // token过期或无效
        if (res.code === 401) {
            const userStore = useUserStore()
            userStore.clearUserInfo()
            const loginStore = useLoginStore()
            loginStore.clearLoginInfo()
            return ElMessage.error('登录已过期，请重新登录');
        }

        return ElMessage.error(res.msg || 'Oh! 响应错误，请尝试联系管理员');
    },
    (error) => {
        error.config && removePending(error.config);
        
        if (axios.isCancel(error)) {
            return ElMessage.warning('已取消的重复请求' + error.message);
        }

        // 处理超时
        if (error.code === 'ECONNABORTED' && error.message.indexOf('timeout') !== -1) {
            return ElMessage.error('请求超时，请稍后重试');
        }

        const { response } = error;
        if (response) {
            const errorMessage = response.data?.message || 'Oh! 请求失败';
            return ElMessage.error(errorMessage)
        }

        return ElMessage.error('网络异常，请检查网络连接');
    }
);

// 请求方法封装
export const http = {
    get<T = any>(url: string, config?: AxiosRequestConfig): Promise<T> {
        return instance.get(url, config);
    },

    post<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T> {
        return instance.post(url, data, config);
    },

    // 上传文件
    upload<T = any>(url: string, file: File): Promise<T> {
        const formData = new FormData();
        formData.append('file', file);
        
        return instance.post(url, formData, {
            headers: {
                'Content-Type': 'multipart/form-data'
            }
        });
    },

    // 下载文件
    download(url: string, filename?: string) {
        return instance.get(url, {
            responseType: 'blob'
        }).then(response => {
            const blob = new Blob([response]);
            const downloadUrl = window.URL.createObjectURL(blob);
            const link = document.createElement('a');
            link.href = downloadUrl;
            link.download = filename || '';
            document.body.appendChild(link);
            link.click();
            document.body.removeChild(link);
            window.URL.revokeObjectURL(downloadUrl);
        });
    }
};

// 导出实例和类型
export type { AxiosInstance, AxiosResponse };
export default instance;

